<template>
  <div class="chat-container">
    <!-- 左侧聊天会话列表 -->
    <div class="chat-sessions">
      <div class="chat-header">
        AI聊天机器人
        <el-button type="primary" style="float: right" @click="openNewSession">开启新会话</el-button>
      </div>
      <ul>
        <li v-for="session in sessions" :key="session.sessionId" @click="selectSession(session)">
          {{ session.sessionName }}
        </li>
      </ul>
    </div>
    <!-- 右侧聊天窗口 -->
    <div class="chat-window">
      <div class="chat-messages" ref="chatMessages">
        <div v-for="message in messages" :key="message" class="message" :class="{ 'sent': message.type === 1 }">
          <pre v-html="message.msg"></pre>
        </div>
      </div>
      <!-- 右侧下方聊天内容输入框 -->
      <div class="chat-input">
        <textarea v-model="newMessage" @keydown.enter="sendMessage" placeholder="请输入问题..."></textarea>
        <button @click="sendMessage">发送</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import hljs from 'highlight.js';
import MarkdownIt from 'markdown-it';
import { nextTick, ref } from 'vue';
import { ask as askApi } from '@/api/rag-api.ts'
import { ElMessage } from "element-plus";

// 初始化MarkdownIt实例
const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: (str, lang) => {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre class="hljs"><code>' +
          hljs.highlight(lang, str, true).value +
          '</code></pre>';
      } catch (__) {
      }
    }

    return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
  }
});
// 引用聊天消息容器
const chatMessages = ref(null);
// 聊天会话列表
const sessions = ref([]);
// 当前选中的会话
const currentSession = ref({});
// 新消息输入框内容
const newMessage = ref('');
// 聊天记录
const messages = ref([]);
// 定义事件源的引用，用于实时通信
const eventSource = ref(null);

// 选择会话
const selectSession = (session) => {
  currentSession.value = session;
  messages.value = [];
  // 查询当前会话聊天记录
  loadMessages();
};


// 创建新会话
const openNewSession = () => {
  newMessage.value = '';
  messages.value = [];
  currentSession.value = {};
};

// 发送消息
const sendMessage = () => {
  const value = newMessage.value;
  if (!value) {
    return ElMessage.warning('请输入问题');
  }
  if (!currentSession.value) {
    // 添加一个模拟的新Session
    const sessionId = '';
    const sessionName = value.length >= 15 ? String(value).substring(0, 15) + '...' : value;
    sessions.value = [{
      sessionName,
      sessionId
    }].concat(sessions.value);
  }
  if (eventSource.value != null) {
    eventSource.value.close();
  }
  // 将用户输入的消息添加到消息列表中，并设置消息类型为用户发送
  messages.value.push({
    msg: newMessage.value,
    type: 1
  });
  messages.value.push({
    msg: '',
    type: 2
  });
  newMessage.value = '';
  let messageOrigin = '';

  const userId = localStorage.getItem('WANGANUI_USER') || '';
  askApi(value, (event) => {
    try {
      let substring = event.data.replaceAll("data:", "");
      let parse = JSON.parse(substring);
      messageOrigin += parse.result?.output?.text;
      if (parse.result?.metadata?.finishReason === "stop") {
        messageOrigin = messageOrigin.replace("<think>", "<div class='think'>").replace("</think>", "</div>");
      }
      messages.value[messages.value.length - 1].msg = md.render(messageOrigin);
      // 调用滚动方法
      scrollToBottom();
      if (!currentSession.value.sessionId) {
        init(false);
      }
    } catch (error) {
      console.error("消息异常:", error);
    }
  });

};

/**
 * 初始化会话列表
 * @param init 是否初次加载
 */
const init = (init) => {
  let userId = localStorage.getItem('WANGANUI_USER');
  // 设置一个默认的用户ID，并存储到缓存
  if (!userId) {
    userId = String(new Date().getTime());
    localStorage.setItem('WANGANUI_USER', userId);
  }
};
// 初始化会话列表
init(true)


/**
 * 滚动到聊天框底部
 */
const scrollToBottom = async () => {
  await nextTick();
  if (chatMessages.value) {
    const lastMessage = chatMessages.value?.children[chatMessages.value.children.length - 1];
    if (lastMessage) {
      lastMessage.scrollIntoView({ behavior: 'smooth', block: 'end' });
    }
  } else {
    console.error('聊天框不可用');
  }
};
</script>

<style scoped lang="scss">
.chat-container {
  display: flex;
  height: 100vh;
  padding: 0;
}

.chat-sessions {
  width: 25%;
  background-color: #f4f4f4;
  padding: 10px;

  .chat-header {
    text-align: center;
    line-height: 30px;
    width: 100%;
  }

  ul {
    list-style-type: none;
    padding: 0;

    li {
      padding: 10px;
      cursor: pointer;

      &:hover {
        background-color: #ddd;
      }
    }
  }
}

.chat-window {
  width: 75%;
  display: flex;
  flex-direction: column;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  background-color: #fff;

  .message {
    margin-bottom: 10px;

    pre {
      background-color: #f9f9f9;
      padding: 10px;
      border-radius: 5px;
      white-space: pre-wrap;
    }

    :deep(.think) {
      display: inline-block;
      padding: 0 10px;
      color: #999999;
      font-size: 13px;
      background-color: #efecec;
      border-radius: 5px;
    }

    &.sent {
      text-align: right;

      pre {
        background-color: #e1ffc7;
      }
    }
  }
}

.chat-input {
  display: flex;
  padding: 10px;

  textarea {
    flex: 1;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
    resize: none;
  }

  button {
    margin-left: 10px;
    padding: 10px 20px;
    border: none;
    background-color: #007bff;
    color: #fff;
    border-radius: 5px;
    cursor: pointer;

    &:hover {
      background-color: #0056b3;
    }
  }
}
</style>
